package com.orphan.marketFront.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.orphan.marketFront.mapper.AllDepositMapper;
import com.orphan.marketFront.mapper.DepositMapper;
import com.orphan.marketFront.po.AllDeposit;
import com.orphan.marketFront.po.Deposit;
import com.orphan.marketFront.service.IDepositService;
import com.orphan.util.dto.DepositDto;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.io.IOException;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author lucangtian
 * @since 2021-07-19
 */
@Service
public class DepositServiceImpl extends ServiceImpl<DepositMapper, Deposit> implements IDepositService {

    @Autowired
    RabbitTemplate rabbitTemplate;
    @Autowired
    AllDepositMapper allDepositMapper;
    @Autowired
    DepositMapper depositMapper;

    @Override
    @Transactional
    public int deposit(Long id, int money, String time) {
        try {
            //先在累计存款表里面查一次，确定是否是第一次存款
            AllDeposit allDeposit = allDepositMapper.selectById(id);
            if (allDeposit != null) {
                allDepositMapper.update(id, money);
//                System.out.println("操作成功");
//                int j = 1 / 0;//测试数据库事务是否成功
            } else {
                allDepositMapper.insert(id, money);
            }
            //再查一次，确定累计存款的主键id
            allDeposit = allDepositMapper.selectById(id);
            int savemoney = depositMapper.savemoney(allDeposit.getDepositId(), money, time);
            return savemoney;
        }catch (Exception e){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return 0;
        }
        //有数据库事务时，不能在service层捕获异常，一旦捕获，那么事务就失效了。
        //具体表现为：假设存钱3次，前2次都异常了，第3次正常，那么前2次的操作都缓存起的，只是没commit，一旦第3次正常，就会commit。
        //就会造成累计存款执行了3次，单次存款只执行了一次(第3次正常的那次)
    }

    /**
     * 回调方法
     */
    RabbitTemplate.ConfirmCallback callback=(CorrelationData correlationData, boolean b, String s)->{
        //投递成功
        if(b){
            //获得关联数据
            String userCorrelationData=correlationData.getId();
            System.out.println(userCorrelationData+"投递成功");
        }
    };

    public void sendDepositInfo(DepositDto depositDto) {
        //开启手动确认
        rabbitTemplate.setMandatory(true);//开启消息确认
        //绑定回调函数
        rabbitTemplate.setConfirmCallback(callback);

        //组装关联数据
        String userName = depositDto.getUserName()+"@"+depositDto.getTime();
        CorrelationData correlationData=new CorrelationData(userName);
        //投递
        rabbitTemplate.convertAndSend("userDepositExchange","userDepositKey",depositDto,correlationData);

    }


//    @RabbitListener(queues = "userDepositQueue")
//    public void getMQMessage(DepositDto depositDto, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long tag) throws IOException {
//
//        System.out.println(depositDto);
//
//        //手动确认  false--不批量确认
//        channel.basicAck(tag,false);
//
//    }
}
